package org.ling.xuan.dao;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import org.ling.xuan.config.DbConfig;
import org.ling.xuan.entity.mo.MarkFile;
import org.ling.xuan.entity.mo.ProjectSetting;
import org.ling.xuan.entity.row.MarkFileRowMapper;
import org.ling.xuan.util.LxStrUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class MarkFileDao {
    public static List<MarkFile> listUnAddFiles() {
        String sql = "select * from mark_file where add_id = '' order by relation,file_path desc";
        return DbConfig.getJdbcTemplate().query(sql, MarkFileRowMapper.INSTANCE);
    }

    public static void mark(String basePath, String filePath, String addId, boolean relation, String remark) {
        LxStrUtil.unionPath(filePath);
        LxStrUtil.unionPath(basePath);
        if (StrUtil.isBlank(addId)) {
            addId = "";
        }
        ProjectSetting projectSetting = ProjectDao.getSetting(basePath);
        MarkFile markFile = new MarkFile();
        markFile.setFileName(FileUtil.getName(filePath));
        markFile.setAddId(addId);
        markFile.setId(StrUtil.uuid());
        markFile.setCtdTime(new Date());
        markFile.setRelation(relation);
        markFile.setProjectId(projectSetting.getId());
        markFile.setRemark(remark);
        markFile.setProjectName(projectSetting.getProjectName());
        markFile.setSvnPath(filePath.replace(projectSetting.getProjectPath(), projectSetting.getSvnPre()));
        markFile.setFilePath(filePath);
        addMarkFile(markFile);
    }

    public static void addMarkFile(MarkFile markFile) {
        String sql = "insert into mark_file (id, project_id, project_name, add_id, svn_path, file_name, file_path, ctd_time, relation,remark) " +
                "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        DbConfig.getJdbcTemplate().update(sql, markFile.getId(), markFile.getProjectId(), markFile.getProjectName(),
                markFile.getAddId(), markFile.getSvnPath(), markFile.getFileName(),
                markFile.getFilePath(), markFile.getCtdTime(), markFile.isRelation(), markFile.getRemark());
    }

    public static void unMark(String basePath, String filePath, String addId) {
        if (StrUtil.isBlank(addId)) {
            addId = "";
        }
        String sql = "delete from mark_file where add_id = ? and file_path=?";
        DbConfig.getJdbcTemplate().update(sql, addId, LxStrUtil.unionPath(filePath));
    }

    public static boolean canMark(String filePath, String addId) {
        if (StrUtil.isBlank(addId)) {
            addId = "";
        }
        String sql = "select count(id) from mark_file where add_id = ? and file_path = ? limit 1";
        Integer i = DbConfig.getJdbcTemplate().queryForObject(sql, Integer.class, addId, LxStrUtil.unionPath(filePath));
        return i == null || i.equals(0);
    }

    public static void updateAddId(String id, List<String> markFileIds) {
        markFileIds = markFileIds.stream().filter(StrUtil::isNotBlank).map(s -> StrUtil.format("'{}'", s)).collect(Collectors.toList());
        String ids = StrUtil.join(",", markFileIds);
        String sql = "update mark_file set add_id = ? where id in (" + ids + ")";
        DbConfig.getJdbcTemplate().update(sql, id);
    }

    public static boolean hasUnMarkFiles() {
        String sql = "select count(id) from mark_file where add_id = '' limit 1";
        Integer i = DbConfig.getJdbcTemplate().queryForObject(sql, Integer.class);
        return i != null && i > 0;
    }

    public static void delete(String id) {
        String sql = "delete from mark_file where id = ?";
        DbConfig.getJdbcTemplate().update(sql, id);
    }

    public static MarkFile getUnMarkFileByPath(String filePath) {
        String sql = "select * from mark_file where add_id = '' and file_path = ?";
        List<MarkFile> files = DbConfig.getJdbcTemplate().query(sql, MarkFileRowMapper.INSTANCE, filePath);
        if (files.size() > 0) {
            return files.get(0);
        } else {
            return null;
        }
    }

    public static List<MarkFile> listByIds(List<String> ids) {
        ids = ids.stream().filter(StrUtil::isNotBlank).map(s -> StrUtil.format("'{}'", s)).collect(Collectors.toList());
        String idsStr = StrUtil.join(",", ids);
        String sql = "select * from mark_file where id in (" + idsStr + ")";
        return DbConfig.getJdbcTemplate().query(sql, MarkFileRowMapper.INSTANCE);

    }

    public static List<MarkFile> listByAddId(String id) {
        String sql = "select * from mark_file where add_id = ? order by relation,file_path desc";
        return DbConfig.getJdbcTemplate().query(sql, MarkFileRowMapper.INSTANCE, id);
    }

    public static List<String> listFileByAddId(String id, boolean relation) {
        String sql = "select file_path from mark_file where add_id = ? and relation = ? order by relation,file_path desc";
        return DbConfig.getJdbcTemplate().query(sql, (rs, rowNum) -> rs.getString("file_path"), id, relation);
    }

    public static List<MarkFile> listByAddIds(Collection<String> addIds) {
        if (addIds.size() > 0) {
            String ids = StrUtil.join(",", addIds);
            String sql = "SELECT mf.* " +
                    "FROM mark_file mf " +
                    "left JOIN ( " +
                    "    SELECT file_path,relation,MAX(ctd_time) AS max_ctd_time " +
                    "    FROM mark_file where add_id in (" + ids + ") " +
                    "    GROUP BY file_path,relation " +
                    ") max_ctd ON mf.file_path = max_ctd.file_path and mf.relation = max_ctd.relation AND mf.ctd_time = max_ctd.max_ctd_time where mf.add_id in(" + ids + ") order by relation,file_path desc";
            return DbConfig.getJdbcTemplate().query(sql, MarkFileRowMapper.INSTANCE);
        } else {
            return new ArrayList<>();
        }
    }

    public static MarkFile getFileByPath(String path, String addId) {
        if (StrUtil.isBlank(addId)) {
            addId = "";
        }
        String sql = "select * from mark_file where add_id = ? and file_path = ? limit 1";
        List<MarkFile> files = DbConfig.getJdbcTemplate().query(sql, MarkFileRowMapper.INSTANCE, addId, path);
        if (files.size() > 0) {
            return files.get(0);
        } else {
            return null;
        }
    }

    public static void saveRemark(String id, String remark) {
        if (StrUtil.isBlank(id)) {
            if (StrUtil.isBlank(remark)) {
                remark = "";
            }
            String sql = "update mark_file set remark = ? where id = ?";
            DbConfig.getJdbcTemplate().update(sql, remark, id);
        }
    }
}
